{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Ollama\n",
    "\n",
    "Ollama는 로컬 환경에서 대규모 언어 모델(LLM)을 쉽게 실행할 수 있게 해주는 오픈소스 프로젝트입니다. 이 도구는 다양한 LLM을 간단한 명령어로 다운로드하고 실행할 수 있게 해주며, 개발자들이 AI 모델을 자신의 컴퓨터에서 직접 실험하고 사용할 수 있도록 지원합니다. Ollama는 사용자 친화적인 인터페이스와 빠른 성능으로, AI 개발 및 실험을 더욱 접근하기 쉽고 효율적으로 만들어주는 도구입니다.\n",
    "\n",
    "- [공식 웹사이트/설치](https://ollama.com/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# API KEY를 환경변수로 관리하기 위한 설정 파일\n",
    "from dotenv import load_dotenv\n",
    "\n",
    "# API KEY 정보로드\n",
    "load_dotenv()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# LangSmith 추적을 설정합니다. https://smith.langchain.com\n",
    "# !pip install langchain-teddynote\n",
    "from langchain_teddynote import logging\n",
    "\n",
    "# 프로젝트 이름을 입력합니다.\n",
    "logging.langsmith(\"CH08-Embeddings\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "texts = [\n",
    "    \"안녕, 만나서 반가워.\",\n",
    "    \"LangChain simplifies the process of building applications with large language models\",\n",
    "    \"랭체인 한국어 튜토리얼은 LangChain의 공식 문서, cookbook 및 다양한 실용 예제를 바탕으로 하여 사용자가 LangChain을 더 쉽고 효과적으로 활용할 수 있도록 구성되어 있습니다. \",\n",
    "    \"LangChain은 초거대 언어모델로 애플리케이션을 구축하는 과정을 단순화합니다.\",\n",
    "    \"Retrieval-Augmented Generation (RAG) is an effective technique for improving AI responses.\",\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**지원되는 임베딩 모델 확인**\n",
    "\n",
    "- https://ollama.com/library"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`ollama pull nomic-embed-text`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.embeddings import OllamaEmbeddings\n",
    "\n",
    "ollama_embeddings = OllamaEmbeddings(\n",
    "    model=\"nomic-embed-text\",\n",
    "    # model=\"chatfire/bge-m3:q8_0\" # BGE-M3\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`Query` 를 임베딩 합니다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 쿼리 임베딩\n",
    "embedded_query = ollama_embeddings.embed_query(\"LangChain 에 대해서 상세히 알려주세요.\")\n",
    "# 임베딩 차원 출력\n",
    "len(embedded_query)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "문서를 임베딩 합니다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 문서 임베딩\n",
    "embedded_documents = ollama_embeddings.embed_documents(texts)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "유사도 계산 결과를 출력합니다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "# 질문(embedded_query): LangChain 에 대해서 알려주세요.\n",
    "similarity = np.array(embedded_query) @ np.array(embedded_documents).T\n",
    "\n",
    "# 유사도 기준 내림차순 정렬\n",
    "sorted_idx = (np.array(embedded_query) @ np.array(embedded_documents).T).argsort()[::-1]\n",
    "\n",
    "# 결과 출력\n",
    "print(\"[Query] LangChain 에 대해서 알려주세요.\\n====================================\")\n",
    "for i, idx in enumerate(sorted_idx):\n",
    "    print(f\"[{i}] 유사도: {similarity[idx]:.3f} | {texts[idx]}\")\n",
    "    print()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "langchain-kr-lwwSZlnu-py3.11",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
